import threading
from typing import Optional

from common.exception_helper import error_handler_produce
from common.produce_logger import debug_produce
from db_tool.db_config import TableName
from db_tool.db_handler import DbHandler
from personal_tool.data_result import DataResult
from web_tool.send_to_web_handler import update_tool_data_in_web
from web_tool.tool_data_model import ToolDataType

db = DbHandler()


class RobotParams:
    """
    机器人参数单例类，线程安全
    """
    _instance: Optional['RobotParams'] = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:  # 双重检查锁定
                    cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, '_initialized'):
            self.reload_robot_params()
            self._initialized = True
            debug_produce("in RobotParams.__init__(): 机器人标定参数初始化完成")

    def reload_robot_params(self):
        """
        从数据库加载机器人参数
        """
        result = db.get_data_one(TableName.robotParams, {"key": "1"})
        if not result.state:
            debug_produce("in RobotParams.reload_robot_params(): 机器人参数加载失败，使用默认值")
        data = result.data if result.data is not None else {}

        # 图像标定点参数
        imagePoint01X = data.get("imagePoint01X", 100)
        imagePoint01Y = data.get("imagePoint01Y", 100)
        imagePoint02X = data.get("imagePoint02X", 500)
        imagePoint02Y = data.get("imagePoint02Y", 103)

        # 机械手标定点参数
        robot01Point01X = data.get("robot01Point01X", 100)
        robot01Point01Y = data.get("robot01Point01Y", 100)
        robot01Angle = data.get("robot01Angle", 0)
        robot02Point01X = data.get("robot02Point01X", 500)
        robot02Point01Y = data.get("robot02Point01Y", 300)
        robot02Angle = data.get("robot02Angle", 0)
        self.rotateAngle01 = data.get("rotateAngle01", 0)
        self.rotateAngle02 = data.get("rotateAngle02", 0)

        self.imageP1 = (imagePoint01X, imagePoint01Y)  # 图像对应的点位1
        self.imageP2 = (imagePoint02X, imagePoint02Y)  # 图像对应的点位2
        self.robot01P1 = (robot01Point01X, robot01Point01Y)  # 机械手1对应的点位1
        self.robot02P1 = (robot02Point01X, robot02Point01Y)  # 机械手2对应的点位1
        self.robot01Angle = robot01Angle  # 机械手1的标定时角度
        self.robot02Angle = robot02Angle  # 机械手2的标定时角度
        debug_produce(f"表 {TableName.robotParams.value} 加载完成: {data}")

    @error_handler_produce
    def update_params(self, newData: dict) -> DataResult:
        """
        更新机器人参数
        :param newData: 新的参数字典
        :return: 是否更新成功
        """
        # 更新数据库
        result = db.update_data(TableName.robotParams, {"key": "1"}, newData)
        if result.state:
            # 更新成功后重新加载参数
            self.reload_robot_params()
        return result

    @staticmethod
    def get_robot_params_from_web() -> DataResult:
        """
        获取机械手标定参数
        """
        update_tool_data_in_web(ToolDataType.robotParams)
        return DataResult(state=True)

    
    def save_robot_params_from_web(self, newData) -> DataResult:
        """
        保存机械手标定参数
        """
        # 这里要先计算出新的K和B然后再保存
        updateRes =  db.update_data(TableName.robotParams, query={"key": "1"},newValues=newData)
        if updateRes.state:
            self.reload_robot_params()
        return updateRes
    
    
if __name__ == '__main__':
    robotParams = RobotParams()
